#include <WiFi.h>
#include <QuickEspNow.h>
#include <esp_sleep.h>
#include <driver/gpio.h>

// RTC内存保存状态
RTC_DATA_ATTR static bool isOpen = false;

// 硬件配置（根据实际接线修改）
static const uint8_t channel = 6;
static const uint8_t buttonPin = 4;   // 按钮引脚
static const uint8_t srcPin = 2;   // 高电平引脚
#ifdef ESP32C3
static const uint8_t ledPin = 8;
#else
static const uint8_t ledPin = 3;
#endif
// 初始化重试参数
int max_retries = 20;      // 最大重试次数
int retry_delay = 50;     // 重试间隔（ms）

static uint8_t cmd = 'o';

void sendCmd() {
    if (isOpen) 
        cmd = 'o';
    else
        cmd='c';
    isOpen = !isOpen;

     // 初始化网络连接
    WiFi.mode(WIFI_MODE_STA);
    WiFi.disconnect(false, true);
    quickEspNow.setWiFiBandwidth(WIFI_IF_AP, WIFI_BW_HT20);
    quickEspNow.begin(channel, WIFI_IF_STA, true);
    
    comms_send_error_t result = COMMS_SEND_CONFIRM_ERROR;
    // 循环重试发送
    for (int retry = 0; retry < max_retries; retry++) {
        result = quickEspNow.send(ESPNOW_BROADCAST_ADDRESS, &cmd, 1);
        if (result == COMMS_SEND_OK) {
            Serial.printf("发送数据到成功！ %d，序号%d\n", result);
            break;  // 发送成功，退出循环
        } else {
            Serial.printf("发送失败！错误码: %d,剩余重试次数: %d\n", result,max_retries - retry - 1);
            delay(retry_delay);  // 等待后重试
        }
    }
    // 最终结果判断
    if (result != COMMS_SEND_OK) {
        Serial.println("10次重试后仍发送失败！");
    }

    // 关闭射频模块（使用正确的方法）
    quickEspNow.stop();
    WiFi.disconnect(true);
    WiFi.mode(WIFI_OFF);
}

void setup() {
    Serial.begin(115200);
      
    // 引脚初始化
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, HIGH);        
    // 修正条件判断（添加缺失的括号）
    if (digitalRead(buttonPin) == HIGH) {  // 完整条件表达式
        sendCmd();
        // 等待按键释放
        while (digitalRead(buttonPin) == HIGH) {
            delay(5);
            //Serial.println("防抖");
        }
    }
    //定义用于RTC_GPIO唤醒的IO，0b为二进制，“0010”为2^(gpio 1)的二进制数
    //gpio0~3 为0b1111，即2^0+2^1+2^2+2^3=15的二进制数
    uint64_t mask = (1ULL << buttonPin) ;
    //const uint64_t WAKEUP_PIN_BITMASK = 0b0010;
    //配置唤醒源 hold disable, isolate and power domain config functions may be unnecessary
    gpio_deep_sleep_hold_dis();	 //在深度睡眠时禁用所有数字gpio pad保持功能。
    //esp_sleep_config_gpio_isolate();
    //esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);

    esp_deep_sleep_enable_gpio_wakeup(mask, ESP_GPIO_WAKEUP_GPIO_HIGH);
    gpio_set_direction((gpio_num_t)buttonPin, GPIO_MODE_INPUT);	//GPIO定向，设置为输入或输出
    gpio_set_direction((gpio_num_t)srcPin, GPIO_MODE_OUTPUT);
    digitalWrite(srcPin, HIGH);
    Serial.end();
    digitalWrite(ledPin, LOW); 
   //开始睡眠
    esp_deep_sleep_start();

 }

void loop() {
}